﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.LIB;
using YArchitech.Revit;
using YJKRGeometry;

namespace HYOpeningDetail
{
	internal class CircularComponent : PointBasedComponent
	{
		public void DimBoxFunction(ElementInfo elementInfo, ViewPlan viewPlan, Dictionary<XYZ, DataWall> dicWallCurve, Dictionary<XYZ, List<Curve>> dicCombineGridCurve, Autodesk.Revit.DB.Document doc, XYZ ptPipeIntersectFloof, Element elem)
		{
			this.m_doc = doc;
			Transaction transaction = new Transaction(this.m_doc, "Dim");
			try
			{
				transaction.Start();
				bool flag = true;
				if (OpeningViewDataSetForm.BRadSelGrid)
				{
					this.CreateLocationDimensionByGridCurve(elementInfo, viewPlan, dicCombineGridCurve, ptPipeIntersectFloof);
				}
				else
				{
					flag = this.CreateLocationDimensionByWallCurve(elementInfo, viewPlan, dicWallCurve, ptPipeIntersectFloof);
				}
				if (flag)
				{
					this.CreateLeaderDimension(elementInfo, viewPlan, ptPipeIntersectFloof, 0);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private bool CreateLocationDimensionByGridCurve(ElementInfo elementInfo, ViewPlan viewPlan, Dictionary<XYZ, List<Curve>> dicCombineGridCurve, XYZ ptPipeIntersectFloof)
		{
			XYZ ptIntersect = null;
			Transform transform = null;
			if (elementInfo.revitLink != null)
			{
				transform = elementInfo.revitLink.GetTransform();
				ptIntersect = transform.OfPoint(ptPipeIntersectFloof);
			}
			else
			{
				ptIntersect = ptPipeIntersectFloof;
			}
			XYZ xyz = null;
			dicCombineGridCurve = (from k in dicCombineGridCurve
			orderby k.Key.DistanceTo(ptIntersect)
			select k).ToDictionary((KeyValuePair<XYZ, List<Curve>> k) => k.Key, (KeyValuePair<XYZ, List<Curve>> k) => k.Value);
			if (dicCombineGridCurve.Count > 0)
			{
				xyz = dicCombineGridCurve.ElementAt(0).Key;
				List<Curve> value = dicCombineGridCurve.ElementAt(0).Value;
				List<Curve> list = new List<Curve>();
				this.GetNewGridInfo(ref xyz, value, ref list, ptIntersect);
				bool flag = this.IsGridIntersecctFace(value[0], elementInfo.element, transform);
				bool flag2 = this.IsGridIntersecctFace(value[1], elementInfo.element, transform);
				if (!flag && !flag2)
				{
					XYZ project = new YJKCurve(list[0]).GetProject(ptIntersect, false);
					XYZ project2 = new YJKCurve(list[1]).GetProject(ptIntersect, false);
					XYZ vectorMove = project.Subtract(xyz).Normalize();
					XYZ vectorMove2 = project2.Subtract(xyz).Normalize();
					Line dimNewLine = Line.CreateBound(project, ptIntersect);
					base.CreateDetailLine(project, ptIntersect, vectorMove, viewPlan, dimNewLine, false);
					Line dimNewLine2 = Line.CreateBound(ptIntersect, project2);
					base.CreateDetailLine(ptIntersect, project2, vectorMove2, viewPlan, dimNewLine2, false);
				}
				if ((flag && !flag2) || (!flag && flag2))
				{
					Curve curve = null;
					if (this.IsGridIntersecctFace(list[0], elementInfo.element, transform))
					{
						curve = list[1];
						Curve curve2 = list[0];
					}
					if (this.IsGridIntersecctFace(list[1], elementInfo.element, transform))
					{
						curve = list[0];
						Curve curve3 = list[1];
					}
					XYZ project3 = new YJKCurve(curve).GetProject(ptIntersect, false);
					XYZ vectorMove3 = (curve as Line).Direction.Normalize();
					Line dimNewLine3 = Line.CreateBound(project3, ptIntersect);
					base.CreateDetailLine(project3, ptIntersect, vectorMove3, viewPlan, dimNewLine3, false);
				}
				return !flag || !flag2;
			}
			return false;
		}

		private bool CreateLocationDimensionByWallCurve(ElementInfo elementInfo, ViewPlan viewPlan, Dictionary<XYZ, DataWall> dicWallCurve, XYZ ptPipeIntersectFloof)
		{
			XYZ ptIntersect = null;
			if (elementInfo.revitLink != null)
			{
				Transform transform = elementInfo.revitLink.GetTransform();
				ptIntersect = transform.OfPoint(ptPipeIntersectFloof);
			}
			else
			{
				ptIntersect = ptPipeIntersectFloof;
			}
			dicWallCurve = (from k in dicWallCurve
			orderby k.Key.DistanceTo(ptIntersect)
			select k).ToDictionary((KeyValuePair<XYZ, DataWall> k) => k.Key, (KeyValuePair<XYZ, DataWall> k) => k.Value);
			if (dicWallCurve.Count <= 0)
			{
				return false;
			}
			DataWall value = dicWallCurve.ElementAt(0).Value;
			XYZ key = dicWallCurve.ElementAt(0).Key;
			double dFirstWallWidth = value.dFirstWallWidth;
			XYZ project = new YJKLine(value.curvrFirst as Line).GetProject(ptIntersect);
			Line lineSec = Line.CreateBound(ptIntersect, project);
			XYZ xyz = ptIntersect.Subtract(project).Normalize();
			XYZ xyz2 = project.Add(xyz * 0.5 * dFirstWallWidth);
			bool flag = this.IsVerticalWithTwoLine(value.curvrFirst as Line, lineSec);
			double dSecondWallWidth = value.dSecondWallWidth;
			XYZ project2 = new YJKLine(value.curveSecond as Line).GetProject(ptIntersect);
			Line lineSec2 = Line.CreateBound(ptIntersect, project2);
			XYZ xyz3 = ptIntersect.Subtract(project2).Normalize();
			XYZ xyz4 = project2.Add(xyz3 * 0.5 * dSecondWallWidth);
			bool flag2 = this.IsVerticalWithTwoLine(value.curveSecond as Line, lineSec2);
			if (flag && flag2)
			{
				Line dimNewLine = Line.CreateBound(ptIntersect, xyz2);
				base.CreateDetailLine(ptIntersect, xyz2, xyz3, viewPlan, dimNewLine, false);
				Line dimNewLine2 = Line.CreateBound(xyz4, ptIntersect);
				base.CreateDetailLine(ptIntersect, xyz4, xyz, viewPlan, dimNewLine2, false);
				return true;
			}
			return false;
		}

		public bool GetFaceCurve(Face face, ref List<Curve> lstCurve)
		{
			EdgeArrayArray edgeLoops = face.EdgeLoops;
			if (edgeLoops.Size < 0)
			{
				return false;
			}
			foreach (object obj in edgeLoops)
			{
				EdgeArray edgeArray = (EdgeArray)obj;
				if (edgeArray.Size >= 0)
				{
					foreach (object obj2 in edgeArray)
					{
						Curve item = ((Edge)obj2).AsCurve();
						lstCurve.Add(item);
					}
				}
			}
			return lstCurve.Count >= 0;
		}

		public bool IsGridIntersecctFace(Curve curGrid, Element elem, Transform transformToDoc)
		{
			List<Face> list = new List<Face>();
			PublicFunction.GetAllFace(elem, ref list, XYZ.BasisZ, null);
            //from i in list
            //orderby -i.Area
            //select i;
			if (list.Count < 0)
			{
				return false;
			}
			Face face = list[list.Count - 1];
			List<Curve> list2 = new List<Curve>();
			if (!this.GetFaceCurve(face, ref list2))
			{
				return false;
			}
			if (transformToDoc != null)
			{
				foreach (Curve curve in list2)
				{
					if (new YJKCurve(Line.CreateBound(new XYZ(curGrid.GetEndPoint(0).X, curGrid.GetEndPoint(0).Y, curve.GetEndPoint(0).Z), new XYZ(curGrid.GetEndPoint(1).X, curGrid.GetEndPoint(1).Y, curve.GetEndPoint(1).Z))).IntersectionAllPoint(curve).Count > 0)
					{
						return true;
					}
				}
				return false;
			}
			List<XYZ> list3 = null;
			foreach (Curve curve2 in list2)
			{
				list3 = new YJKCurve(Line.CreateBound(new XYZ(curGrid.GetEndPoint(0).X, curGrid.GetEndPoint(0).Y, curve2.GetEndPoint(0).Z), new XYZ(curGrid.GetEndPoint(1).X, curGrid.GetEndPoint(1).Y, curve2.GetEndPoint(1).Z))).IntersectionAllPoint(curve2);
			}
			if (list3.Count > 0)
			{
				return true;
			}
			return false;
		}

		private void GetNewGridInfo(ref XYZ ptGridIntersect, List<Curve> lstGridCurve, ref List<Curve> lstNewGridCurve, XYZ ptFamInstance)
		{
			ptGridIntersect = new XYZ(ptGridIntersect.X, ptGridIntersect.Y, ptFamInstance.Z);
			foreach (Curve curve in lstGridCurve)
			{
				Line item = Line.CreateBound(new XYZ(curve.GetEndPoint(0).X, curve.GetEndPoint(0).Y, ptFamInstance.Z), new XYZ(curve.GetEndPoint(1).X, curve.GetEndPoint(1).Y, ptFamInstance.Z));
				lstNewGridCurve.Add(item);
			}
		}

		private bool CreateLeaderDimension(ElementInfo elementInfo, ViewPlan viewPlan, XYZ ptPipeIntersectFloof, int iBoxCategory)
		{
			XYZ xyz;
			if (elementInfo.revitLink != null)
			{
				xyz = elementInfo.revitLink.GetTransform().OfPoint(ptPipeIntersectFloof);
			}
			else
			{
				xyz = ptPipeIntersectFloof;
			}
			double value = 0.0;
			double num = 0.0;
			double num2 = 0.0;
			Parameter parameter = base.GetParameter(elementInfo.element, "直径");
			Parameter parameter2 = base.GetParameter(elementInfo.element, "宽度");
			Parameter parameter3 = base.GetParameter(elementInfo.element, "高度");
			if (parameter != null)
			{
				value = NumbericTools.feetTomm(parameter.AsDouble());
			}
			if (parameter2 != null)
			{
				num = NumbericTools.feetTomm(parameter2.AsDouble());
			}
			if (parameter3 != null)
			{
				num2 = NumbericTools.feetTomm(parameter3.AsDouble());
			}
			string str = Convert.ToInt32(num + 100.0).ToString();
			string str2 = Convert.ToInt32(num2 + 120.0).ToString();
			XYZ ptDimPosionFir = new XYZ(xyz.X + NumbericTools.mmToFeet(800.0), xyz.Y - NumbericTools.mmToFeet(400.0), xyz.Z);
			if (elementInfo.element is Pipe)
			{
				string text = "DN" + Convert.ToInt32(value).ToString();
				base.LeaderDimension(xyz, ptDimPosionFir, text, text, viewPlan);
			}
			else if (elementInfo.element is CableTray)
			{
				ElementId typeId = (elementInfo.element as CableTray).GetTypeId();
				string text = this.m_doc.GetElement(typeId).Name + str + "X" + str2;
				string strLevelText = "靠墙安装";
				base.LeaderDimension(xyz, ptDimPosionFir, text, strLevelText, viewPlan);
			}
			return true;
		}

		private bool IsVerticalWithTwoLine(Line lineFir, Line lineSec)
		{
			XYZ xyz = lineFir.Direction.Normalize();
			XYZ xyz2 = lineSec.Direction.Normalize();
			return Geometry.IsEqual(xyz.AngleTo(xyz2), Math.PI*.5);
		}
	}
}
